<template>
  <!-- 滑动解锁插件 http://www.jq22.com/jquery-info22779 -->
  <div
    ref="dragVerify"
    class="drag_verify"
    :style="dragVerifyStyle"
    @mousemove="dragMoving"
    @mouseup="dragFinish"
    @mouseleave="dragFinish"
    @touchmove="dragMoving"
    @touchend="dragFinish"
  >
    <div class="dv_progress_bar" ref="progressBar" :class="{ goFirst2: isOk }" :style="progressBarStyle"></div>
    <div class="dv_text" :style="textStyle" ref="message">
      <slot name="textBefore" v-if="$slots.textBefore"></slot>
      {{ message }}
      <slot name="textAfter" v-if="$slots.textAfter"></slot>
    </div>

    <div
      class="dv_handler dv_handler_bg"
      :class="{ goFirst: isOk }"
      @mousedown="dragStart"
      @touchstart="dragStart"
      ref="handler"
      :style="handlerStyle"
    >
      <i :class="handlerIcon"></i>
    </div>
  </div>
</template>
<script>
export default {
  name: 'dragVerify',
  props: {
    // 是否通过
    isPassing: {
      type: Boolean,
      default: false
    },
    // 宽度
    width: {
      type: Number,
      default: 250
    },
    // 高度
    height: {
      type: Number,
      default: 40
    },
    // 组件文案
    text: {
      type: String,
      default: 'swiping to the right side'
    },
    // 成功文案
    successText: {
      type: String,
      default: 'success'
    },
    // 背景色
    background: {
      type: String,
      default: '#eee'
    },
    // 解锁中背景色
    progressBarBg: {
      type: String,
      default: '#76c61d'
    },
    // 解锁成功背景色
    completedBg: {
      type: String,
      default: '#76c61d'
    },
    circle: {
      type: Boolean,
      default: false
    },
    radius: {
      type: String,
      default: '4px'
    },
    handlerIcon: {
      type: String
    },
    successIcon: {
      type: String
    },
    handlerBg: {
      type: String,
      default: '#fff'
    },
    textSize: {
      type: String,
      default: '14px'
    },
    textColor: {
      type: String,
      default: '#333'
    }
  },
  mounted() {
    const dragEl = this.$refs.dragVerify
    dragEl.style.setProperty('--textColor', this.textColor)
    dragEl.style.setProperty('--width', Math.floor(this.width / 2) + 'px')
    dragEl.style.setProperty('--pwidth', -Math.floor(this.width / 2) + 'px')
  },
  computed: {
    handlerStyle() {
      return {
        left: '0px',
        width: this.height + 'px',
        height: this.height + 'px',
        background: this.handlerBg
      }
    },
    message() {
      return this.isPassing ? this.successText : this.text
    },
    dragVerifyStyle() {
      return {
        width: this.width + 'px',
        height: this.height + 'px',
        lineHeight: this.height + 'px',
        background: this.background,
        borderRadius: this.circle ? this.height / 2 + 'px' : this.radius
      }
    },
    progressBarStyle() {
      return {
        background: this.progressBarBg,
        height: this.height + 'px',
        borderRadius: this.circle ? this.height / 2 + 'px 0 0 ' + this.height / 2 + 'px' : this.radius
      }
    },
    textStyle() {
      return {
        height: this.height + 'px',
        width: this.width + 'px',
        fontSize: this.textSize
      }
    }
  },
  data() {
    return {
      isMoving: false,
      x: 0,
      isOk: false
    }
  },
  methods: {
    dragStart(e) {
      if (!this.isPassing) {
        this.isMoving = true
        var handler = this.$refs.handler
        this.x = (e.pageX || e.touches[0].pageX) - parseInt(handler.style.left.replace('px', ''), 10)
      }
      this.$emit('handlerMove')
    },
    dragMoving(e) {
      if (this.isMoving && !this.isPassing) {
        var _x = (e.pageX || e.touches[0].pageX) - this.x
        var handler = this.$refs.handler
        if (_x > 0 && _x <= this.width - this.height) {
          handler.style.left = _x + 'px'
          this.$refs.progressBar.style.width = _x + this.height / 2 + 'px'
        } else if (_x > this.width - this.height) {
          handler.style.left = this.width - this.height + 'px'
          this.$refs.progressBar.style.width = this.width - this.height / 2 + 'px'
          this.passVerify()
        }
      }
    },
    dragFinish(e) {
      if (this.isMoving && !this.isPassing) {
        var _x = (e.pageX || e.changedTouches[0].pageX) - this.x
        if (_x < this.width - this.height) {
          this.isOk = true
          var that = this
          setTimeout(function() {
            that.$refs.handler.style.left = '0'
            that.$refs.progressBar.style.width = '0'
            that.isOk = false
          }, 500)
        } else {
          var handler = this.$refs.handler
          handler.style.left = this.width - this.height + 'px'
          this.$refs.progressBar.style.width = this.width - this.height / 2 + 'px'
          this.passVerify()
        }
        this.isMoving = false
      }
    },
    passVerify() {
      this.$emit('update:isPassing', true)
      this.isMoving = false
      var handler = this.$refs.handler
      handler.children[0].className = this.successIcon
      this.$refs.progressBar.style.background = this.completedBg
      this.$refs.message.style['-webkit-text-fill-color'] = 'unset'
      this.$refs.message.style.animation = 'slidetounlock2 3s infinite'
      this.$refs.message.style.color = '#fff'
      this.$emit('passcallback')
    },
    reset() {
      const oriData = this.$options.data()
      for (const key in oriData) {
        if (oriData.hasOwnProperty(key)) {
          this.$set(this, key, oriData[key])
        }
      }
      var handler = this.$refs.handler
      var message = this.$refs.message
      handler.style.left = '0'
      this.$refs.progressBar.style.width = '0'
      handler.children[0].className = this.handlerIcon
      message.style['-webkit-text-fill-color'] = 'transparent'
      message.style.animation = 'slidetounlock 3s infinite'
      message.style.color = this.background
    }
  }
}
</script>
<style lang="stylus" scoped>
.drag_verify {
  position: relative;
  background-color: #e8e8e8;
  text-align: center;
  overflow: hidden;

  .dv_handler {
    position: absolute;
    top: 0px;
    left: 0px;
    cursor: move;

    i {
      color: #666;
      padding-left: 0;
      font-size: 16px;
    }

    .el-icon-circle-check {
      color: #6c6;
      margin-top: 9px;
    }
  }

  .dv_progress_bar {
    position: absolute;
    height: 34px;
    width: 0px;
  }

  .dv_text {
    position: absolute;
    top: 0px;
    color: transparent;
    -moz-user-select: none;
    -webkit-user-select: none;
    user-select: none;
    -o-user-select: none;
    -ms-user-select: none;
    background: -webkit-gradient(
      linear,
      left top,
      right top,
      color-stop(0, var(--textColor)),
      color-stop(0.4, var(--textColor)),
      color-stop(0.5, #fff),
      color-stop(0.6, var(--textColor)),
      color-stop(1, var(--textColor))
    );
    -webkit-background-clip: text;
    -webkit-text-fill-color: transparent;
    -webkit-text-size-adjust: none;
    animation: slidetounlock 3s infinite;

    * {
      -webkit-text-fill-color: var(--textColor);
    }
  }

  .goFirst {
    left: 0px !important;
    transition: left 0.5s;
  }

  .goFirst2 {
    width: 0px !important;
    transition: width 0.5s;
  }
}
</style>
<style>
@keyframes slidetounlock {
  0% {
    background-position: var(--pwidth) 0;
  }
  100% {
    background-position: var(--width) 0;
  }
}
@keyframes slidetounlock2 {
  0% {
    background-position: var(--pwidth) 0;
  }
  100% {
    background-position: var(--pwidth) 0;
  }
}
</style>
